home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Tools / Utility / PCI Peek / PCIPeek 2.1 Project / PCIPeek.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  32.3 KB  |  1,014 lines  |  [TEXT/MPCC]

  1. /*
  2. * © Copyright 1995, Jano Banks, Paul Freeburn
  3. *
  4. * Name:           PCIPeek.c
  5. * Authors:        Jano Banks, Paul Freeburn.
  6. * Description:     Peek and poke at PCI components in the system using MacOS system calls.
  7. *
  8. *
  9. * Revision History:
  10. * Date        Initials    Description
  11. * ----      --------    -----------
  12. * 5/26/95    jdb            1. Remade to fully use NameRegistry/Expansion Manager and get rid of 
  13. *                        hardware-direct mode.
  14. *                        2.    Updated menus.
  15. *                        3.    Create way to use unit-address to select exact device.
  16. *                        4.  Took out CAPS-LOCK requirement
  17. *
  18. * Improvements planned
  19. * --------------------
  20. *                        1.  List PCI Devices
  21. *                        2.  Add full featured PCI Compliance Test (crdtst module).
  22. *                        
  23. */
  24.  
  25. #pragma segment robix
  26.  
  27. #include "PCIPeek.h"
  28.  
  29.  
  30. /************************************* Global Variables *********************************************/
  31.     RegEntryID    NodeID;
  32.     Boolean    NodeIDSelected;
  33.     OSErr        anErr;
  34.     int            InputBase = 16;    // default to hex input
  35.     
  36.     
  37.     char Command[8];    // allows for 8-character commands
  38.     char arg1[132];        // allows for 132-character entry
  39.     char arg2[132];        // allows for 132-character entry
  40.     char arg3[132];        // allows for 132-character entry
  41.     char arg4[132];        // allows for 132-character entry
  42.  
  43.  
  44.  
  45.  
  46.  
  47. /************************************* Functions *********************************************/
  48. /* Fill in the help menu when you add a new command */
  49. void Help()
  50. {
  51.     printf("--------------------------------------------------------------------\n");
  52.     printf("DXY <addr>         -->    Display (Read) X=B/W/L/P, Y=C/I/M/T\r\n");
  53.     printf("\tDBC < 8-bit hex addr> = Reads 8-bits from current node's Configuration Space\n");
  54.     printf("\tDWC < 8-bit hex addr> = Reads 16-bits byte-reversed from current node's Configuration Space\n");
  55.     printf("\tDLC < 8-bit hex addr> = Reads 32-bits byte-reversed from current node's Configuration Space\n");
  56.     printf("\tDPC < 8-bit hex addr  8-bit page length> = Reads page 8-bits (default 128-bytes) from current node's Configuration Space\n");
  57.     printf("\tDBI <32-bit hex addr> = Reads 8-bits from current node's IO Space\n");
  58.     printf("\tDWI <32-bit hex addr> = Reads 16-bits byte-reversed from current node's IO Space\n");
  59.     printf("\tDLI <32-bit hex addr> = Reads 32-bits byte-reversed from current node's IO Space\n");
  60.     printf("\tDPI <32-bit hex addr 12-bit page length> = Reads page 8-bits (default 128-bytes) from current node's IO Space\n");
  61.     printf("\tDBM <32-bit hex addr> = Reads 8-bits from any memory location\n");
  62.     printf("\tDWM <32-bit hex addr> = Reads 16-bits byte-reversed from any memory location\n");
  63.     printf("\tDLM <32-bit hex addr> = Reads 32-bits byte-reversed from any memory location\n");
  64.     printf("\tDPM <32-bit hex addr 12-bit page length> = Reads page 8-bits (default 128-bytes) from any memory location\n");
  65.  
  66.     printf("\tDBT <no args>         = Reads 8-bits from current node with an Interrupt Acknowledge Cycle\n");
  67.     printf("\tDWT <no args>         = Reads 16-bits byte-reversed from current node with an Interrupt Acknowledge Cycle\n");
  68.     printf("\tDLT <no args>         = Reads 32-bits byte-reversed from current node with an Interrupt Acknowledge Cycle\n");
  69.     printf("\n");
  70.  
  71.     printf("SXY <addr data>    -->    Set (Write) X=B/W/L, Y=C/I/M/S/B\n");
  72.     printf("\tSBC < 8-bit hex addr 8-bit hex data>  = Writes 8-bits to current node's Configuration Space\n");
  73.     printf("\tSWC < 8-bit hex addr 16-bit hex data> = Writes 16-bits byte-reversed to current node's Configuration Space\n");
  74.     printf("\tSLC < 8-bit hex addr 32-bit hex data> = Writes 32-bits byte-reversed to current node's Configuration Space\n");
  75.     printf("\tSBI <32-bit hex addr 8-bit hex data>  = Writes 8-bits to current node's IO Space\n");
  76.     printf("\tSWI <32-bit hex addr 16-bit hex data> = Writes 16-bits byte-reversed to current node's IO Space\n");
  77.     printf("\tSLI <32-bit hex addr 32-bit hex data> = Writes 32-bits byte-reversed to current node's IO Space\n");
  78.     printf("\tSBM <32-bit hex addr 8-bit hex data>  = Writes 8-bits to any memory location\n");
  79.     printf("\tSWM <32-bit hex addr 16-bit hex data> = Writes 16-bits byte-reversed to any memory location\n");
  80.     printf("\tSLM <32-bit hex addr 32-bit hex data> = Writes 32-bits byte-reversed to any memory location\n");
  81.     printf("\tSLS <32-bit hex data 32-bit hex data> = Writes 32-bits byte-reversed to PCIBus where current node lives with Special Cycle\n");
  82.     printf("\tSLB <32-bit hex data 32-bit hex data> = Writes 32-bits byte-reversed to all PCIBuses in the system with Special Cycle\n");
  83.     printf("\n");
  84.     
  85.     printf("C <no args>    -->    Displays current node's PCI Configuration Header (first 64 bytes of Configuration Space)\n");
  86.     printf("\n");
  87.     
  88.     printf("N <no args> --> To select new node name\n");
  89.     printf("\n");
  90.  
  91.     printf("? <no args> --> Prints this menu\n");
  92.     printf("--------------------------------------------------------------------\n");
  93.     printf("\n");
  94. }
  95.  
  96.  
  97. /*****************************************************
  98.         function ProcessCommand_D
  99.  
  100. ProcessCommand_D processes input string for
  101.     DXY --> Display (Byte/Word/Long) to (Config/IO/Mem/IntAck)
  102. *****************************************************/
  103. void ProcessCommand_D(const int numOfArgs)
  104.     {    
  105.     
  106.     UInt32     Address;
  107.     UInt32    Data;
  108.     UInt8    TransLength;
  109.     UInt8    TransType;
  110.     UInt8      value8;
  111.     UInt16     value16;    
  112.     UInt32     value32;    
  113.     UInt8      NoAddressCycle;
  114.     UInt8    NoDataCycle;
  115.     
  116. //    char    **unusedptr;
  117.     
  118.     TransLength = False; // 0
  119.     TransType = False;   // 0
  120.     NoAddressCycle = False; //0
  121.     NoDataCycle = False;   //0
  122.  
  123.     
  124.     switch (Command[1])
  125.     {
  126.         case 'B' :
  127.             TransLength = lengthByte;
  128.             break;
  129.         case 'W' :
  130.             TransLength = lengthWord;
  131.             break;
  132.         case 'L' :
  133.             TransLength = lengthLongword;
  134.             break;
  135.         case 'P' :
  136.             TransLength = lengthPage; 
  137.             break;
  138.     }
  139.     
  140.     if (TransLength)
  141.     {
  142.         switch (Command[2])
  143.         {
  144.             case 'C' :
  145.                 TransType = typeConfig;
  146.                 break;
  147.             case 'I' :
  148.                 TransType = typeIO;
  149.                 break;
  150.             case 'M' :
  151.                 TransType = typeMemory;
  152.                 break;
  153.             case 'T' :
  154.                 TransType = interruptAcknowledge;
  155.                 NoAddressCycle = True;
  156.                 break;    
  157.         }
  158.         
  159.         if (TransType)
  160.         {
  161.             if (numOfArgs > 1) 
  162.             {
  163. //                Address = strtoul(arg1, unusedptr, InputBase);
  164.                 Address = strtoul(arg1, NULL, InputBase);
  165.                         
  166.                 if(numOfArgs > 2)
  167.                     Data = strtoul(arg2, NULL, InputBase);
  168.                 else
  169.                     Data = 128;                                            /* default page to 128 bytes */
  170.                             
  171.  
  172.                     switch (TransLength | TransType)
  173.                     {
  174.                     /* Config Read Cycles */                    
  175.                     case (lengthByte | typeConfig) :
  176.                         anErr = ExpMgrConfigReadByte(&NodeID, (LogicalAddress)Address, &value8);
  177.                         if (anErr == noErr)
  178.                             printf("%02X\n",value8);
  179.                         else
  180.                             printf("ERROR: Bad call to ExpMgrConfigReadByte.  Error Code = %d\n", anErr);
  181.                         break;
  182.  
  183.                     case (lengthWord | typeConfig) :
  184.                         anErr = ExpMgrConfigReadWord(&NodeID, (LogicalAddress)Address, &value16);
  185.                         if (anErr == noErr)
  186.                             printf("%04X\n",value16);
  187.                         else
  188.                             printf("ERROR: Bad call to ExpMgrConfigReadWord.  Error Code = %d\n", anErr);
  189.                         break;
  190.  
  191.                     case (lengthLongword | typeConfig) :
  192.                         anErr = ExpMgrConfigReadLong(&NodeID, (LogicalAddress)Address, &value32);
  193.                         if (anErr == noErr)
  194.                             printf("%08X\n",value32);
  195.                         else
  196.                             printf("ERROR: Bad call to ExpMgrConfigReadLong.  Error Code = %d\n", anErr);
  197.                         break;
  198.  
  199.                     case (lengthPage | typeConfig) :
  200.                         if(Data > 256)
  201.                             Data = 256;
  202.                         if(Address > 256)
  203.                             Address = 0;                                                    /* limit config dispaly to 256 bytes */
  204.                         printf("\n");
  205.                         printf("Displaying Configuration Space from %02X\n",Address);
  206.                         DisplayMemoryIOConfig(Address, Data, TransType);            /* display page(s) of memory, I/O, or Config space */
  207.                         break;
  208.  
  209.  
  210.                     /* IO Read Cycles */                    
  211.                     case (lengthByte | typeIO) :
  212.                         anErr = ExpMgrIOReadByte(&NodeID, (LogicalAddress)Address, &value8);
  213.                         if (anErr == noErr)
  214.                             printf("%02X\n",value8);
  215.                         else
  216.                             printf("ERROR: Bad call to ExpMgrIOReadByte.  Error Code = %d\n", anErr);
  217.                         break;
  218.  
  219.                     case (lengthWord | typeIO) :
  220.                         anErr = ExpMgrIOReadWord(&NodeID, (LogicalAddress)Address, &value16);
  221.                         if (anErr == noErr)
  222.                             printf("%04X\n",value16);
  223.                         else
  224.                             printf("ERROR: Bad call to ExpMgrIOReadWord.  Error Code = %d\n", anErr);
  225.                         break;
  226.  
  227.                     case (lengthLongword | typeIO) :
  228.                         anErr = ExpMgrIOReadLong(&NodeID, (LogicalAddress)Address, &value32);
  229.                         if (anErr == noErr)
  230.                             printf("%08X\n",value32);
  231.                         else
  232.                             printf("ERROR: Bad call to ExpMgrIOReadLong.  Error Code = %d\n", anErr);
  233.                         break;
  234.  
  235.                     case (lengthPage | typeIO) :
  236.                         printf("\n");
  237.                         printf("Displaying IO Space from %02X\n",Address);
  238.                         DisplayMemoryIOConfig(Address, Data, TransType);            /* display page(s) of memory, I/O, or Config space */
  239.                         break;
  240.  
  241.  
  242.                     /* Memory Read Cycles */                    
  243.                     case (lengthByte | typeMemory) :
  244.                         value8 = *(volatile UInt8 *)Address;
  245.                         printf("%02X\n",value8);
  246.                         break;
  247.  
  248.                     case (lengthWord | typeMemory) :
  249.                         value16 = *(volatile UInt16 *)Address;
  250.                         printf("%04X\n",EndianSwap16Bit(value16));
  251.                         break;
  252.  
  253.                     case (lengthLongword | typeMemory) :
  254.                         value32 = *(volatile UInt32 *)Address;
  255.                         printf("%08X\n",EndianSwap32Bit(value32));
  256.                         break;
  257.  
  258.                     case (lengthPage | typeMemory) :
  259.                         printf("\n");
  260.                         printf("Displaying Memory Space from %02X\n",Address);
  261.                         DisplayMemoryIOConfig(Address, Data, TransType);            /* display page(s) of memory, I/O, or Config space */
  262.                         break;
  263.                     }        
  264.             }
  265.             else    /* No address for an interrupt acknowledge cycle */
  266.             {
  267.                 switch (TransLength | TransType)
  268.                 {
  269.                 /* Interrupt Acknowledge Read Cycles */                    
  270.                     case (lengthByte | interruptAcknowledge) :
  271.                         anErr = ExpMgrInterruptAcknowledgeReadByte(&NodeID, &value8);
  272.                         if (anErr == noErr)
  273.                             printf("%02X\n",value8);
  274.                         else
  275.                             printf("ERROR: Bad call to ExpMgrInterruptAcknowledgeReadByte.  Error Code = %d\n", anErr);
  276.                         break;
  277.                             
  278.                     case (lengthWord | interruptAcknowledge) :
  279.                         anErr = ExpMgrInterruptAcknowledgeReadWord(&NodeID, &value16);
  280.                         if (anErr == noErr)
  281.                             printf("%04X\n",value16);
  282.                         else
  283.                             printf("ERROR: Bad call to ExpMgrInterruptAcknowledgeReadWord.  Error Code = %d\n", anErr);
  284.                         break;
  285.                         
  286.                     case (lengthLongword | interruptAcknowledge) :
  287.                         anErr = ExpMgrInterruptAcknowledgeReadLong(&NodeID, &value32);
  288.                         if (anErr == noErr)
  289.                             printf("%08X\n",value32);
  290.                         else
  291.                             printf("ERROR: Bad call to ExpMgrInterruptAcknowledgeReadLong.  Error Code = %d\n", anErr);
  292.                 }        
  293.  
  294.                 if (!NoAddressCycle)
  295.                     printf("No address entered.  No action performed.\n");
  296.             }
  297.         }
  298.         else
  299.         {
  300.             printf("Invalid Transfer Type (C/I/M/T valid).  No action performed.\n");
  301.         }
  302.     }
  303.     else
  304.     {
  305.         printf("Invalid Transfer Length (B/W/L valid).  No action performed.\n");
  306.     }
  307. }
  308.  
  309.  
  310. /*****************************************************
  311.         function DisplayMemoryIOConfig
  312.  
  313. Displays memory, I/O, and or Config space starting @ StartAddress
  314. and for DisplayLength bytes, or a Page of 128 bytes.
  315. *****************************************************/
  316. void DisplayMemoryIOConfig(UInt32 StartAddress, UInt32 DisplayLength, UInt8 CycleType)
  317.     {
  318.     
  319.     UInt32    TempAddress;
  320.     UInt8    InputPage[32];
  321.     UInt8    num8;
  322.     int        cntByte;
  323.     int        j;
  324.     int        k;
  325.  
  326.     if(DisplayLength > 4096)
  327.         DisplayLength = 4096;                                                /* set maximum length to 4K */
  328.     if(DisplayLength < 16)
  329.         DisplayLength = DisplayLength + 16;    
  330.         
  331.  
  332.     for(DisplayLength = DisplayLength/16; DisplayLength > 0; DisplayLength--)
  333.         {
  334.             TempAddress = StartAddress;
  335.             j = 0;
  336.                         
  337.  
  338.             switch (CycleType)
  339.             {
  340.                 case typeMemory :
  341.                 
  342.                     while (j < 16)
  343.                         {
  344.                         InputPage[j] = *(volatile UInt8 *)StartAddress++;    /* read a line (16 bytes) of memory space */
  345.                         j++;
  346.                         }
  347.                     break;
  348.                 
  349.                 case typeIO :
  350.                 
  351.                     while (j < 16)
  352.                         {
  353.                         anErr = ExpMgrIOReadByte(&NodeID, (LogicalAddress)StartAddress++, &num8);    /* read a line (16 bytes) of I/O space */
  354.                         if (anErr == noErr)
  355.                             {
  356.                             InputPage[j] = num8;
  357.                             j++;
  358.                             }
  359.                             
  360.                         else
  361.                             {
  362.                             printf("\n");
  363.                             printf("ERROR: Bad call to ExpMgrIOReadByte.  Error Code = %d\n", anErr);
  364.                             j = 16;                                                                            /* set loop indexes to done */
  365.                             DisplayLength = 0;
  366.                             }
  367.                         }
  368.                     break;
  369.                 
  370.                 case typeConfig :
  371.                 
  372.                         while (j < 16)
  373.                             {
  374.                             anErr = ExpMgrConfigReadByte(&NodeID, (LogicalAddress)StartAddress++, &num8);    /* read a line (16 bytes) of config space */
  375.                             if (anErr == noErr)
  376.                                 {
  377.                                 InputPage[j] = num8;
  378.                                 j++;
  379.                                 }
  380.                                 
  381.                             else
  382.                                 {
  383.                                 printf("\n");
  384.                                 printf("ERROR: Bad call to ExpMgrConfigReadByte.  Error Code = %d\n", anErr);
  385.                                 j = 16;                                                                            /* set loop indexes to done */
  386.                                 DisplayLength = 0;
  387.                                 }
  388.                             }
  389.                         break;
  390.             }
  391.  
  392.                 StartAddress = TempAddress;
  393.                 j = 0;
  394.                 k = 0;
  395.                 printf("%02X  ",StartAddress);
  396.                 cntByte = 0;
  397.                 
  398.                 while (cntByte < 8)                                /* display 16 Bytes in Hex */
  399.                     {
  400.                         printf("%02X", InputPage[j]);
  401.                         j++;
  402.                         StartAddress++;
  403.                         printf("%02X", InputPage[j]);
  404.                         j++;
  405.                         StartAddress++;
  406.                         printf(" ");
  407.                         cntByte++;
  408.                     }
  409.                             
  410.                     printf(" ");
  411.                     cntByte = 0;
  412.                     
  413.                     while (cntByte < 16)                        /* display ascii equivalent */
  414.                         {
  415.                             if(InputPage[k] <= 0X20 || InputPage[k] >= 0XD9)
  416.                                 InputPage[k] = 0X2E;
  417.                                     
  418.                             printf("%c", InputPage[k]);
  419.                             k++;
  420.                             cntByte++;
  421.                         }    
  422.                             
  423.                             printf("\n");
  424.                 }            
  425.     }
  426.  
  427.  
  428.  
  429.  
  430. /*****************************************************
  431.         function ProcessCommand_S
  432.  
  433. ProcessCommand_S processes input string for
  434.     SXY --> Set (Byte/Word/Long) to (Config/IO/Mem/Spec/SpecBroadcast)
  435. *****************************************************/
  436. void ProcessCommand_S(const int numOfArgs)
  437.     {    
  438.  
  439.     UInt32    Address;
  440.     UInt32    Data;
  441.     UInt8    TransLength;
  442.     UInt8    TransType;
  443.     UInt8      NoDataCycle;    
  444. //    char    **unusedptr;
  445.     
  446.     TransLength = False;
  447.     TransType = False;
  448.     NoDataCycle = False;
  449.  
  450.     
  451.     switch (Command[1])
  452.     {
  453.         case 'B' :
  454.             TransLength = lengthByte;
  455.             break;
  456.         case 'W' :
  457.             TransLength = lengthWord;
  458.             break;
  459.         case 'L' :
  460.             TransLength = lengthLongword;
  461.             break;
  462.     }
  463.     
  464.     if (TransLength)
  465.     {
  466.         switch (Command[2])
  467.         {
  468.             case 'C' :
  469.                 TransType = typeConfig;
  470.                 break;
  471.             case 'I' :
  472.                 TransType = typeIO;
  473.                 break;
  474.             case 'M' :
  475.                 TransType = typeMemory;
  476.                 break;
  477.             case 'S' :
  478.                 TransType = typeSpecialWrite;
  479.                 NoDataCycle = True;
  480.                 break;
  481.             case 'B' :
  482.                 TransType = typeSpecialBroadcast;
  483.                 NoDataCycle = True;
  484.                 break;
  485.                 
  486.         }
  487.         
  488.         if (TransType)
  489.         {
  490.             if (numOfArgs > 1) 
  491.             {
  492. //                Address = strtoul(arg1, unusedptr, InputBase);
  493.                 Address = strtoul(arg1, NULL, InputBase);
  494.                     
  495.                 if (numOfArgs > 2) 
  496.                 {
  497. //                    Data = strtoul(arg2, unusedptr, InputBase);
  498.                     Data = strtoul(arg2, NULL, InputBase);
  499.  
  500.                     switch (TransLength | TransType)
  501.                     {
  502.                     
  503.                     /* Config Write Cycles */                    
  504.                         case (lengthByte | typeConfig) :
  505.                             anErr = ExpMgrConfigWriteByte(&NodeID, (LogicalAddress)Address, (UInt8)Data);
  506.                             if (anErr != noErr)
  507.                                 printf("ERROR: Bad call to ExpMgrConfigWriteByte.  Error Code = %d\n", anErr);
  508.                             break;
  509.  
  510.                         case (lengthWord | typeConfig) :
  511.                             anErr = ExpMgrConfigWriteWord(&NodeID, (LogicalAddress)Address, (UInt16)Data);
  512.                             if (anErr != noErr)
  513.                                 printf("ERROR: Bad call to ExpMgrConfigWriteWord.  Error Code = %d\n", anErr);
  514.                             break;
  515.                         
  516.                         case (lengthLongword | typeConfig) :
  517.                             anErr = ExpMgrConfigWriteLong(&NodeID, (LogicalAddress)Address, Data);
  518.                             if (anErr != noErr)
  519.                                 printf("ERROR: Bad call to ExpMgrConfigWriteLong.  Error Code = %d\n", anErr);
  520.                             break;
  521.  
  522.                     /* IO Write Cycles */                    
  523.                         case (lengthByte | typeIO) :
  524.                             anErr = ExpMgrIOWriteByte(&NodeID, (LogicalAddress)Address, (UInt8)Data);
  525.                             if (anErr != noErr)
  526.                                 printf("ERROR: Bad call to ExpMgrIOWriteByte.  Error Code = %d\n", anErr);
  527.                             break;
  528.  
  529.                         case (lengthWord | typeIO) :
  530.                             anErr = ExpMgrIOWriteWord(&NodeID, (LogicalAddress)Address, (UInt16)Data);
  531.                             if (anErr != noErr)
  532.                                 printf("ERROR: Bad call to ExpMgrIOWriteWord.  Error Code = %d\n", anErr);
  533.                             break;
  534.                         
  535.                         case (lengthLongword | typeIO) :
  536.                             anErr = ExpMgrIOWriteLong(&NodeID, (LogicalAddress)Address, Data);
  537.                             if (anErr != noErr)
  538.                                 printf("ERROR: Bad call to ExpMgrIOWriteLong.  Error Code = %d\n", anErr);
  539.                             break;
  540.                         
  541.                     /* Memory Write Cycles */                    
  542.                         case (lengthByte | typeMemory) :
  543.                             *(volatile UInt8 *)Address = (UInt8)Data;
  544.                             break;
  545.                         case (lengthWord | typeMemory) :
  546.                             *(volatile UInt16 *)Address = EndianSwap16Bit((UInt16)Data);
  547.                             break;
  548.                         case (lengthLongword | typeMemory) :
  549.                             *(volatile UInt32 *)Address = EndianSwap32Bit(Data);
  550.                             break;
  551.                             
  552.                             
  553.                     }
  554.                 }
  555.                 else /* no 2nd argument for Special Cycles */
  556.                 {
  557.  
  558.                     switch (TransLength | TransType)
  559.                     {
  560.                         case (lengthLongword | typeSpecialWrite) :
  561.                             anErr = ExpMgrSpecialCycleWriteLong(&NodeID, Address);    /* Address is really data, but Address variable saved first above */
  562.                             if (anErr != noErr)
  563.                                 printf("ERROR: Bad call to ExpMgrSpecialCycleWriteLong.  Error Code = %d\n", anErr);
  564.                             break;
  565.                                     
  566.                         case (lengthLongword | typeSpecialBroadcast) :
  567.                             anErr = ExpMgrSpecialCycleBroadcastLong(Address);
  568.                             if (anErr != noErr)
  569.                                 printf("ERROR: Bad call to ExpMgrSpecialCycleBroadcastLong.  Error Code = %d\n", anErr);
  570.                             break;
  571.                     }        
  572.                     if(!NoDataCycle)    /* This means no 2nd Arg for other write transactions */
  573.                         printf("No data entered.  No action performed.\n");
  574.                 }
  575.             }
  576.             else
  577.             {
  578.                 if(!NoDataCycle)    
  579.                     printf("No address entered.  No action performed.\n");    /* for non Special Cycle checking */
  580.                 else
  581.                     printf("No data entered.  No action performed.\n");        /* for Special Cycle checking */
  582.             }
  583.         }
  584.         else
  585.         {
  586.             printf("Invalid Transfer Type (C/I/M/S/B valid).  No action performed.\n");
  587.         }
  588.     }
  589.     else
  590.     {
  591.         printf("Invalid Transfer Length (B/W/L valid).  No action performed.\n");
  592.     }
  593. }
  594.  
  595.  
  596. // ------------------------------------------------
  597. // FindPropertyWithValue
  598. //     Find a node with a specific property and value in the Registry
  599. // jdb: propertyNamePtr is the string to match
  600. //        propertyValue is the value of the property
  601. //        foundEntry is the returned node id.
  602. //        returns:    1.  noErr if foundEntry is updated
  603. //                    2.  done if done is true (got to end of device tree and didn't find property)
  604. //                    3.  an error if Registry routines return an error.
  605. // ------------------------------------------------
  606. OSStatus FindPropertyWithValue(const RegPropertyName *propertyName, const void *propertyValue, const RegPropertyValueSize propertySize, RegEntryID *foundEntry)
  607. {
  608.     RegEntryIter             cookie; 
  609.     RegEntryID                 theEntry; 
  610.     RegEntryIterationOp     iterOp; 
  611.     Boolean                 done; 
  612.     OSStatus                 err = noErr;
  613. /*
  614.     RegPropertyValueSize    tempSize;
  615.     RegPropertyValueSize    tempSize2;
  616.     RegPropertyName            *temppropertyNamePtr;
  617.     RegPropertyName            temppropertyName;
  618.     RegCStrEntryName        *tempCharPtr;
  619. */
  620.     RegistryEntryIDInit(&theEntry);
  621.  
  622.     err = RegistryEntryIterateCreate(&cookie); 
  623.     if (err != noErr) 
  624.         return err;
  625.  
  626.     iterOp = kRegIterContinue; 
  627. /*
  628.     tempSize = sizeof("Big_Bird");
  629.     tempSize2 = sizeof(0x81000000);
  630.     temppropertyNamePtr = propertyName;
  631.     temppropertyName = *propertyName;
  632.     tempCharPtr = (RegCStrEntryName *) propertyValue;
  633. */
  634.     err = RegistryEntrySearch(&cookie, iterOp, &theEntry, &done, 
  635.                             propertyName, propertyValue, propertySize);
  636.  
  637.     if (!done && (err == noErr)) 
  638.     { 
  639.         *foundEntry = theEntry; 
  640.     }
  641.     else if (done) 
  642.         err = done; 
  643.  
  644.     RegistryEntryIDDispose(&theEntry); 
  645.     RegistryEntryIterateDispose(&cookie);
  646.      
  647.     return err; 
  648. }
  649.  
  650.  
  651. OSStatus FindNameWithUnitAddr(const void *nodeNameValue, const RegPropertyValueSize nodeNameSize, const UInt32 unitAddr, RegEntryID *foundEntry)
  652. {
  653.     RegEntryIter             cookie; 
  654.     RegEntryID                 theEntry; 
  655.     RegEntryIterationOp     iterOp; 
  656.     Boolean                 done; 
  657.     OSStatus                 err = noErr;
  658.  
  659.     RegPropertyValueSize    SizeOfReg;
  660.     void                     *regValue;
  661.     UInt32                    *ThisUnitAddr;
  662.         
  663.     #define SizeOfunitAddr    4;
  664.  
  665.     RegistryEntryIDInit(&theEntry);
  666.  
  667.     err = RegistryEntryIterateCreate(&cookie); 
  668.     if (err != noErr) 
  669.         return err;
  670.  
  671.     iterOp = kRegIterContinue; 
  672.  
  673.     do 
  674.     {
  675.         err = RegistryEntrySearch(&cookie, iterOp, &theEntry, &done, 
  676.                                 "name", nodeNameValue, nodeNameSize);
  677.     
  678.         if (!done && (err == noErr))    /* we found a name match, now let's check if unit addr matches */
  679.         { 
  680.             err = RegistryPropertyGetSize(&theEntry, "reg", &SizeOfReg);            /* need this node's reg property size */
  681.             if (err != noErr)
  682.                 return err;        
  683.             
  684.             regValue = NULL;                                                        /* allocate space for a local variable */
  685.             regValue = NewPtr(SizeOfReg);                                            /* in Memory.h */
  686.             if (regValue == NULL)
  687.             {
  688.                 printf("ERROR: No memory available to store property value.\n");
  689.                 return ERR_MEMALLOC;
  690.             }
  691.  
  692.             err = RegistryPropertyGet(&theEntry, "reg", regValue, &SizeOfReg);        /* get the reg value */
  693.             if (err != noErr)
  694.                 return err;        
  695.             
  696.             ThisUnitAddr = regValue;                                                /* pointer now to a UInt32 */
  697.             
  698.             if (*ThisUnitAddr == unitAddr)                                            /* if it matches, fill in return value */
  699.                 *foundEntry = theEntry; 
  700.         }
  701.     }    while (!done && (err == noErr) && (*ThisUnitAddr != unitAddr));                /* otherwise, keep going */
  702.     
  703.     if (done)
  704.         err = done;        /* if we got through the whole Name Registry without a match, that's an error */
  705.     RegistryEntryIDDispose(&theEntry); 
  706.     RegistryEntryIterateDispose(&cookie);
  707.      
  708.     return err; 
  709. }
  710.  
  711.  
  712.  
  713. OSStatus MessageDeviceUnderTest(const RegEntryID *theEntry)
  714. {
  715.     OSStatus                 err;
  716.     RegPropertyValueSize    SizeOfProp;
  717.     void                     *propValue;
  718.     UInt32                    *unitAddr;
  719.     PCIUnitAddressPtr        unitAddrParts;
  720.     PCIBusNumber            theBusNumber;
  721.     PCIDeviceFunction        theDeviceAndFunction;
  722.     
  723.     /* print statement */
  724.     printf("Current node info:\n");
  725.         
  726.     /* first get the name of the node */
  727.     printf("\tName:\t\t\t");
  728.     err = RegistryPropertyGetSize(theEntry, "name", &SizeOfProp);                        /* need node's name property size */
  729.     if (err == noErr)
  730.     {
  731.         propValue = NULL;                                                                    /* allocate space for a local variable */
  732.         propValue = NewPtr(SizeOfProp);                                                        /* in Memory.h */
  733.         if (propValue == NULL)
  734.         {
  735.             printf("\nERROR: No memory available to store property value.\n");
  736.             return ERR_MEMALLOC;
  737.         }
  738.     
  739.         err = RegistryPropertyGet(theEntry, "name", propValue, &SizeOfProp);                /* get the name value */
  740.         if (err != noErr)
  741.             return err;
  742.         
  743.         /* print name */
  744.         printf("%s\n",(char *) propValue);
  745.     }
  746.     else /* no name? Must be first time through (no node yet) */
  747.         printf("Unknown\n");
  748.  
  749.     /* now get the AAPL,slot-name */
  750.     printf("\tSlot:\t\t\t");
  751.     err = RegistryPropertyGetSize(theEntry, "AAPL,slot-name", &SizeOfProp);                /* need node's AAPL,slot-name property size */
  752.     if (err == noErr)
  753.     {        
  754.         propValue = NULL;                                                                    /* allocate space for a local variable */
  755.         propValue = NewPtr(SizeOfProp);                                                        /* in Memory.h */
  756.         if (propValue == NULL)
  757.         {
  758.             printf("\nERROR: No memory available to store property value.\n");
  759.             return ERR_MEMALLOC;
  760.         }
  761.         err = RegistryPropertyGet(theEntry, "AAPL,slot-name", propValue, &SizeOfProp);        /* get the name value */
  762.         if (err != noErr)
  763.             return err;
  764.         /* print AAPL,slot-name */
  765.         printf("%s\n",(char *) propValue);    
  766.     }
  767.     else if (err == nrNotFoundErr)    /* some PCI devices are on the motherboard */
  768.         printf("Motherboard device\n");
  769.     else /* other errors occur if first time through (no node yet) */
  770.         printf("Unknown\n");
  771.     
  772.     /* now get the unit-address portion of the reg property */
  773.     printf("\tUnit-Address:\t");
  774.     err = RegistryPropertyGetSize(theEntry, "reg", &SizeOfProp);                            /* need node's reg property size */
  775.     if (err == noErr)
  776.     {        
  777.         propValue = NULL;                                                                    /* allocate space for a local variable */
  778.         propValue = NewPtr(SizeOfProp);                                                        /* in Memory.h */
  779.         if (propValue == NULL)
  780.         {
  781.             printf("\nERROR: No memory available to store property value.\n");
  782.             return ERR_MEMALLOC;
  783.         }
  784.         err = RegistryPropertyGet(theEntry, "reg", propValue, &SizeOfProp);        /* get the name value */
  785.         if (err != noErr)
  786.             return err;
  787.         
  788.         unitAddr         = propValue;                                            /* pointer to Full number */
  789.         unitAddrParts     = propValue;                                            /* pointer to same, but with parts breakdown */
  790.         printf("%X\n", *unitAddr);
  791.         
  792.         theBusNumber             = unitAddrParts->busNumber;
  793.         theDeviceAndFunction     = unitAddrParts->deviceFunctionNumber;
  794.         printf("\t\tBus Number:\t\t\t%2X\n",theBusNumber);    
  795.         printf("\t\tDevice Number:\t\t%2X\n",((theDeviceAndFunction>>3) & kPCIDeviceNumberMask));    
  796.         printf("\t\tFunction Number:\t%2X\n",(theDeviceAndFunction & kPCIFunctionNumberMask));    
  797.     }
  798.     else    /* no reg(unit-address)?  Could be at initialization time (no node yet) or FCode hosed */
  799.         printf("Unknown\n");
  800.     
  801.     return err;
  802. }
  803.  
  804.  
  805. OSStatus DisplayConfiguration(const RegEntryID *theEntry)
  806. {
  807.     OSStatus err;
  808.     UInt8 ConfigHeader[64];
  809.     int i;
  810.     
  811.     err = noErr;
  812.     i = 0;
  813.     while ((err == noErr) & (i < 64))
  814.     {
  815.         err = ExpMgrConfigReadByte((RegEntryIDPtr)theEntry, (LogicalAddress)i, &ConfigHeader[i]);
  816.         i++;
  817.     }
  818.     if (err != noErr)
  819.     {
  820.         printf("ERROR: Bad call to ExpMgrConfigReadByte.  Error Code = %d\n", err);
  821.         return err;
  822.     }
  823.     
  824.     /* common to all PCI Devices (first 16 bytes) */
  825.     printf("Vendor ID        = %02X%02X     | 0x00\n",  ConfigHeader[0x01],ConfigHeader[0x00]);
  826.     printf("Device ID        = %02X%02X     | 0x02\n",  ConfigHeader[0x03],ConfigHeader[0x02]);
  827.     printf("Command          = %02X%02X     | 0x04\n",  ConfigHeader[0x05],ConfigHeader[0x04]);
  828.     printf("Status           = %02X%02X     | 0x06\n",  ConfigHeader[0x07],ConfigHeader[0x06]);
  829.     printf("Revision ID      = %02X       | 0x08\n",ConfigHeader[0x08]);
  830.     printf("Class Code       = %02X%02X%02X   | 0x09\n",    ConfigHeader[0x0B],ConfigHeader[0x0A],ConfigHeader[0x09]);
  831.     printf("Cache line size  = %02X       | 0x0C\n",ConfigHeader[0x0C]);
  832.     printf("Latency          = %02X       | 0x0D\n",ConfigHeader[0x0D]);
  833.     printf("Header type      = %02X       | 0x0E\n",ConfigHeader[0x0E]);
  834.     printf("BIST             = %02X       | 0x0F\n",ConfigHeader[0x0F]);
  835.     
  836.     /* rest of standard header */
  837.     if ((ConfigHeader[0xE] & 0x01) == 0x00)    
  838.     {
  839.     printf("Base addr 0      = %02X%02X%02X%02X | 0x10\n",      ConfigHeader[0x13],ConfigHeader[0x12],ConfigHeader[0x11],ConfigHeader[0x10]);
  840.     printf("Base addr 1      = %02X%02X%02X%02X | 0x14\n",      ConfigHeader[0x17],ConfigHeader[0x16],ConfigHeader[0x15],ConfigHeader[0x14]);
  841.     printf("Base addr 2      = %02X%02X%02X%02X | 0x18\n",      ConfigHeader[0x1B],ConfigHeader[0x1A],ConfigHeader[0x19],ConfigHeader[0x18]);
  842.     printf("Base addr 3      = %02X%02X%02X%02X | 0x1C\n",      ConfigHeader[0x1F],ConfigHeader[0x1E],ConfigHeader[0x1D],ConfigHeader[0x1C]);
  843.     printf("Base addr 4      = %02X%02X%02X%02X | 0x20\n",      ConfigHeader[0x23],ConfigHeader[0x22],ConfigHeader[0x21],ConfigHeader[0x20]);
  844.     printf("Base addr 5      = %02X%02X%02X%02X | 0x24\n",      ConfigHeader[0x27],ConfigHeader[0x26],ConfigHeader[0x25],ConfigHeader[0x24]);
  845.     printf("Cardbus CIS Ptr  = %02X%02X%02X%02X | 0x28\n",      ConfigHeader[0x2B],ConfigHeader[0x2A],ConfigHeader[0x29],ConfigHeader[0x28]);
  846.     printf("Subsys Vendor ID = %02X%02X     | 0x2C\n",  ConfigHeader[0x2D],ConfigHeader[0x2C]);
  847.     printf("Subsys ID        = %02X%02X     | 0x2E\n",  ConfigHeader[0x2F],ConfigHeader[0x2E]);
  848.     printf("ROM base         = %02X%02X%02X%02X | 0x30\n",      ConfigHeader[0x33],ConfigHeader[0x32],ConfigHeader[0x31],ConfigHeader[0x30]);
  849.     printf("Reserved         = %02X%02X%02X%02X | 0x34\n",      ConfigHeader[0x37],ConfigHeader[0x36],ConfigHeader[0x35],ConfigHeader[0x34]);
  850.     printf("Reserved         = %02X%02X%02X%02X | 0x38\n",      ConfigHeader[0x3B],ConfigHeader[0x3A],ConfigHeader[0x39],ConfigHeader[0x38]);
  851.     printf("Interrupt line   = %02X       | 0x3C\n",ConfigHeader[0x3C]);
  852.     printf("Interrupt pin    = %02X       | 0x3D\n",ConfigHeader[0x3D]);
  853.     printf("Min_Gnt          = %02X       | 0x3E\n",ConfigHeader[0x3E]);
  854.     printf("Max_Lat          = %02X       | 0x3F\n",ConfigHeader[0x3F]);
  855.     }
  856.     
  857.     /* rest of PCI 2 PCI header */
  858.     else if ((ConfigHeader[0xE] & 0x01) == 0x01)
  859.     {
  860.     printf("Base addr 0      = %02X%02X%02X%02X | 0x10\n",      ConfigHeader[0x13],ConfigHeader[0x12],ConfigHeader[0x11],ConfigHeader[0x10]);
  861.     printf("Base addr 1      = %02X%02X%02X%02X | 0x14\n",      ConfigHeader[0x17],ConfigHeader[0x16],ConfigHeader[0x15],ConfigHeader[0x14]);
  862.     printf("Primary Bus #    = %02X       | 0x18\n",ConfigHeader[0x18]);
  863.     printf("2ndary Bus #     = %02X       | 0x19\n",ConfigHeader[0x19]);
  864.     printf("Subordinate Bus# = %02X       | 0x1A\n",ConfigHeader[0x1A]);
  865.     printf("2ndary Lat Timer = %02X       | 0x1B\n",ConfigHeader[0x1B]);
  866.     printf("IO Base          = %02X       | 0x1C\n",ConfigHeader[0x1C]);
  867.     printf("IO Limit         = %02X       | 0x1D\n",ConfigHeader[0x1D]);
  868.     printf("2ndary Status    = %02X%02X     | 0x1E\n",  ConfigHeader[0x1F],ConfigHeader[0x1E]);
  869.     printf("Memory Base      = %02X%02X     | 0x20\n",  ConfigHeader[0x21],ConfigHeader[0x20]);
  870.     printf("Memory Limit     = %02X%02X     | 0x22\n",  ConfigHeader[0x23],ConfigHeader[0x22]);
  871.     printf("Prefetch Mem Base= %02X%02X     | 0x24\n",  ConfigHeader[0x25],ConfigHeader[0x24]);
  872.     printf("Prefetch Mem Lim = %02X%02X     | 0x26\n",  ConfigHeader[0x27],ConfigHeader[0x26]);
  873.     printf("Pftch Base Upr 32= %02X%02X%02X%02X | 0x28\n",      ConfigHeader[0x2B],ConfigHeader[0x2A],ConfigHeader[0x29],ConfigHeader[0x28]);
  874.     printf("Pftch Lim  Upr 32= %02X%02X%02X%02X | 0x2C\n",      ConfigHeader[0x2F],ConfigHeader[0x2E],ConfigHeader[0x2D],ConfigHeader[0x2C]);
  875.     printf("IO Base Upper 16 = %02X%02X     | 0x30\n",  ConfigHeader[0x31],ConfigHeader[0x30]);
  876.     printf("IO Lim  Upper 16 = %02X%02X     | 0x32\n",  ConfigHeader[0x33],ConfigHeader[0x32]);
  877.     printf("Reserved         = %02X%02X%02X%02X | 0x34\n",      ConfigHeader[0x37],ConfigHeader[0x36],ConfigHeader[0x35],ConfigHeader[0x34]);
  878.     printf("ROM base         = %02X%02X%02X%02X | 0x38\n",      ConfigHeader[0x3B],ConfigHeader[0x3A],ConfigHeader[0x39],ConfigHeader[0x38]);
  879.     printf("Interrupt line   = %02X       | 0x3C\n",ConfigHeader[0x3C]);
  880.     printf("Interrupt pin    = %02X       | 0x3D\n",ConfigHeader[0x3D]);
  881.     printf("Bridge Control   = %02X%02X     | 0x3E\n",  ConfigHeader[0x3F],ConfigHeader[0x3E]);
  882.     }
  883.  
  884.     /* rest of unknown header */
  885.     else
  886.     {
  887.         printf("!! Unknown Header Type !! Listing below is just addresses and longword data,ConfigHeader\n");
  888.         for (i = 16; i < 64; i=i+4)
  889.         {
  890.         printf("                 = %02X%02X%02X%02X | 0x%02X\n",ConfigHeader[i+3],ConfigHeader[i+2],ConfigHeader[i+1],ConfigHeader[i],i);
  891.         }
  892.     }
  893.     return err;
  894.  
  895. }
  896.  
  897.  
  898. void GetNodeName()
  899. {
  900.     UInt32 unitAddr;
  901.     int numOfArgs;
  902.     OSErr err;
  903.     Boolean Done;
  904.     char InNameNode[132];
  905.     char nodeName[132];
  906.     
  907.     Done = FALSE;
  908.     while (!Done)
  909.     {
  910.         printf("Enter new node name =>");
  911.         gets(InNameNode);
  912.         if(strcmp(InNameNode, "") == 0)    /* if nothing entered */
  913.         {
  914.             if (NodeIDSelected == FALSE)
  915.                 printf("\tNo node selected yet.\n");
  916.             else
  917.             {
  918.                 printf("\tNo Change.\n");
  919.                 Done = TRUE;
  920.             }
  921.         }
  922.         else
  923.         {
  924.             numOfArgs = sscanf(InNameNode, "%s %x", nodeName, &unitAddr);
  925.             if (numOfArgs == 1)    /* they're just matching name */
  926.             {
  927.                 err = FindPropertyWithValue("name", nodeName, strlen(nodeName)+1, &NodeID);
  928.             }
  929.             if (numOfArgs == 2)    /* they're trying to get a node ID from a name and unit address */
  930.             {
  931.                 err = FindNameWithUnitAddr(nodeName, strlen(nodeName)+1, unitAddr, &NodeID);
  932.             }
  933.             
  934.             if(err != noErr)
  935.             {
  936.                 printf("Device node %s is not in the device tree\n", InNameNode);
  937.             }
  938.             else     
  939.                 Done = TRUE;
  940.         }
  941.     }
  942.     err = MessageDeviceUnderTest(&NodeID);
  943.     
  944. }    
  945.  
  946. void ToUpperString(Ptr theString)
  947. {
  948.     short lengthOfString ;
  949.     
  950.     lengthOfString = strlen((char *)theString);
  951.     UpperText(theString, lengthOfString);            /* from TextUtils.h */
  952. }
  953.  
  954. /************************************* Main Loop ********************************************/
  955.  
  956. void main()
  957. {
  958.     UInt8 Exit;
  959.     int numOfArgs;
  960.     char CommandLine[132];
  961.  
  962.     Exit = False;
  963.     NodeIDSelected = FALSE;
  964.  
  965.     printf("***** PCIPeek 2.1  6/95,  Let's you peek and poke your PCI devices! *****\n\n");
  966.     printf("\tOriginated by: Rob Glanville, Jano Banks, Mike Regal, and Al Scalise\n");
  967.     printf("\tModified by: Jano Banks and Paul Freeburn\n\n");
  968.         
  969.     Help();                        // print the menu
  970.     GetNodeName();                // get the initial Node Name
  971.     NodeIDSelected = TRUE;        // can't get out of GetNodeName unless it is!
  972.  
  973.         
  974.     while (!Exit) 
  975.     {
  976.  
  977.         printf(">");
  978.         gets(CommandLine);
  979.         numOfArgs = sscanf(CommandLine, "%s %s %s %s %s", Command, arg1, arg2, arg3, arg4);
  980.         switch (numOfArgs)
  981.         {
  982.             case 5:     ToUpperString((Ptr)arg4);
  983.             case 4:     ToUpperString((Ptr)arg3);
  984.             case 3:     ToUpperString((Ptr)arg2);
  985.             case 2:     ToUpperString((Ptr)arg1);
  986.             case 1:        ToUpperString((Ptr)Command);
  987.         }
  988.         
  989.         switch(Command[0]) 
  990.         {
  991.             case '?' :
  992.                 Help();
  993.                 break;
  994.             case 'N' :
  995.                 GetNodeName();
  996.                 break;    
  997.             case 'C' :
  998.                 DisplayConfiguration(&NodeID);
  999.                 break;
  1000.             case 'D' :
  1001.                 ProcessCommand_D(numOfArgs);
  1002.                 break;
  1003.             case 'S' :
  1004.                 ProcessCommand_S(numOfArgs);
  1005.                 break;
  1006.             default :
  1007.                 printf("Unknown command\n");
  1008.                 break;
  1009.         }
  1010.     }
  1011. }
  1012.  
  1013.  
  1014.